#ifndef __CODE_COMMENT_GEN_H_
#define __CODE_COMMENT_GEN_H_

#include "code_comment_info.h"

#include "clang/AST/ASTConsumer.h"
#include "clang/AST/ASTContext.h"
#include "clang/Basic/FileManager.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Frontend/FrontendAction.h"
#include "clang/Tooling/Refactoring.h"
#include "clang/Tooling/Tooling.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/Support/Errc.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/JSON.h"
#include "clang/AST/RecursiveASTVisitor.h"

#include <string>
#include <vector>
#include <map>

using namespace llvm;

class CodeCommentGenASTConsumer : public clang::RecursiveASTVisitor<CodeCommentGenASTConsumer>, 
                                  public clang::ASTConsumer
{
public:
    explicit CodeCommentGenASTConsumer(CodeCommentInfoManager& codeCommentInfoManager)
        : mCodeCommentInfoManager(codeCommentInfoManager)
        {}
    
    ~CodeCommentGenASTConsumer() {}

    void HandleTranslationUnit(clang::ASTContext& Context) override;
    bool VisitNamespaceDecl(const clang::NamespaceDecl *D);
    bool VisitRecordDecl(const clang::RecordDecl *D);
    bool VisitEnumDecl(const clang::EnumDecl *D);
    bool VisitCXXMethodDecl(const clang::CXXMethodDecl *D);
    bool VisitFunctionDecl(const clang::FunctionDecl *D);

    void doWriteOut();

private:
    clang::comments::FullComment *getComment(const clang::NamedDecl *D,
                                    const clang::ASTContext &Context);
    llvm::StringRef getCommentStr(const clang::NamedDecl *D, const clang::ASTContext &Context);
    
private:
    CodeCommentInfoManager& mCodeCommentInfoManager;
};

#endif  // __CODE_COMMENT_GEN_H_